package com.atguigu.gmall.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.*;
import com.atguigu.gmall.client.service.OrderFeignClientService;
import com.atguigu.gmall.config.AlipayConfig;
import com.atguigu.gmall.constant.MqConst;
import com.atguigu.gmall.entity.OrderInfo;
import com.atguigu.gmall.entity.PaymentInfo;
import com.atguigu.gmall.enums.PaymentStatus;
import com.atguigu.gmall.enums.PaymentType;
import com.atguigu.gmall.enums.ProcessStatus;
import com.atguigu.gmall.mapper.PaymentInfoMapper;
import com.atguigu.gmall.result.RetVal;
import com.atguigu.gmall.service.PaymentInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Transactional
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {

    @Autowired
    private OrderFeignClientService orderFeignClientService;
    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override

    public String createQrCode(Long orderId) throws AlipayApiException {
        //获取订单信息
        OrderInfo orderInfo = orderFeignClientService.findOrderById(orderId);
        //保存支付信息
        this.savePaymentInfo(orderInfo, PaymentType.ALIPAY.name());
        //创建支付宝的的请求
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        //设置同步回调地址
        alipayRequest.setReturnUrl(AlipayConfig.return_payment_url);
        //设置异步回调地址，供支付宝回调时使用，（支付后调用接口，回应用户的支付状态）
        alipayRequest.setNotifyUrl(AlipayConfig.notify_payment_url);
        //声明一个map 集合，存储支付相关信息
//        HashMap<String, Object> map = new HashMap<>();
        Map<String, Object> map = new ConcurrentHashMap<>();//线程安全
        map.put("out_trade_no", orderInfo.getOutTradeNo());
        map.put("product_code", "FAST_INSTANT_TRADE_PAY");
        map.put("total_amount", orderInfo.getTotalMoney());
        map.put("subject", "测试阿里支付");
        alipayRequest.setBizContent(JSON.toJSONString(map));
        return alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单,也就是支付的二维码
    }

    @Override
    public PaymentInfo getPaymentInfo(String outTradeNo, String paymentType) {
        QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("out_trade_no", outTradeNo).eq("payment_type", paymentType);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public void updatePaymentInfo(String outTradeNo, String paymentType, Map<String, String> paramMap) {
        //先查寻出该支付订单
        PaymentInfo paymentInfo = this.getPaymentInfo(outTradeNo, paymentType);
        /*再次确认！！！*/
        if (paymentInfo != null) {
            //判断查询到的数据支付状态，如果支付状态已经修改，则不需要在进行修改
            if (paymentInfo.getPaymentStatus().equals(PaymentStatus.PAID.name()) ||
                    paymentInfo.getPaymentStatus().equals(PaymentStatus.ClOSED.name())) {
                return;
            }
            //执行更新操作
            paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
            paymentInfo.setCallbackTime(new Date());
            paymentInfo.setCallbackContent(paramMap.toString());
            paymentInfo.setTradeNo(paramMap.get("trade_no"));
            //设置更新的条件
            QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("out_trade_no", outTradeNo);
            baseMapper.update(paymentInfo, wrapper);
            //通知orderinfo 修改订单状态  发生了类型转换 string -》 long
            rabbitTemplate.convertAndSend(MqConst.PAY_ORDER_EXCHANGE, MqConst.PAY_ORDER_ROUTE_KEY, paymentInfo.getOrderId());
        }
    }

    @Override
    public boolean refund(Long orderId) throws AlipayApiException {
        // 根据退款接口：(out_trade_no || trade_no) && refund_amount
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        // out_trade_no ,在订单表，交易记录表都有，并这两个是同一个值！
        OrderInfo orderInfo = orderFeignClientService.findOrderById(orderId);
        // 创建一个map
        HashMap<String, Object> refundDataMap = new HashMap<>();
        refundDataMap.put("out_trade_no",orderInfo.getOutTradeNo());
        refundDataMap.put("refund_amount",orderInfo.getTotalMoney());
        refundDataMap.put("refund_reason","空调不够凉");
        request.setBizContent(JSON.toJSONString(refundDataMap));
        AlipayTradeRefundResponse response = alipayClient.execute(request);;
        if(response.isSuccess()){
            //更新支付状态
            QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("order_id", orderId);
            PaymentInfo paymentInfo = baseMapper.selectOne(queryWrapper);
            if (paymentInfo!=null){
                paymentInfo.setPaymentStatus(ProcessStatus.CLOSED.name());
                baseMapper.updateById(paymentInfo);
            }
            return true;
        } else {
            System.out.println("调用失败");
            return false;
        }

    }

    @Override
    public boolean closeAlipayTrade(Long orderId) throws AlipayApiException {
        //获取订单详情
        OrderInfo orderInfo = orderFeignClientService.findOrderById(orderId);
        //封装查询参数
        Map<String, Object> map = new HashMap<>();
        map.put("out_trade_no", orderInfo.getOutTradeNo());

        AlipayTradeCloseRequest alipayTradeCloseRequest = new AlipayTradeCloseRequest();
        alipayTradeCloseRequest.setBizContent(JSONObject.toJSONString(map));
        AlipayTradeCloseResponse response = alipayClient.execute(alipayTradeCloseRequest);
        return response.isSuccess();//返回关闭订单是否成功
    }

    @Override
    public boolean queryAlipayTrade(Long orderId) throws AlipayApiException {
        OrderInfo orderInfo = orderFeignClientService.findOrderById(orderId);
        HashMap<String, Object> map = new HashMap<>();
        map.put("out_trade_no",orderInfo.getOutTradeNo());
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizContent(JSON.toJSONString(map));
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        return response.isSuccess();

    }

    private void savePaymentInfo(OrderInfo orderInfo, String paymentType) {
        //先查询是否已经创建了订单
        QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orderInfo.getId()).eq("payment_type", paymentType);
        Integer count = baseMapper.selectCount(queryWrapper);
        if (count > 0)
            return;   //已经存在了订单信息
        //封装结果
        PaymentInfo paymentInfo = new PaymentInfo();//创建一个paymentInfo 对象
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(orderInfo.getId() + "");
        paymentInfo.setPaymentType(paymentType);
        paymentInfo.setPaymentMoney(orderInfo.getTotalMoney());
        paymentInfo.setPaymentContent(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());
        paymentInfo.setCreateTime(new Date());
        baseMapper.insert(paymentInfo);
    }
}
